#include <memory>
#include "UdpServer.hpp"
#include "InetAddr.hpp"
#include "Route.hpp"
#include "Thread.hpp"
#include "ThreadPool.hpp"

using namespace myThreadPool;


//现在来写第三个版本 -> chat server系统

// ./UDP_SERVER.exe  port
int main(int argc, char* argv[]){
    if(argc != 2){
        std::cerr << "please usage : " << "./UDP_SERVER  port" << std::endl;
        return 1;
    }

    int port = std::stoi(std::string(argv[1]));
    
     //1.这个是单进程(服务器)进行收发
    /* Route route;

    std::unique_ptr<UdpServer> Pserver = std::make_unique<UdpServer>(port, 
        [&route](std::string message, const InetAddr& send_client){route.MessageRoute(message, send_client);});  */



    //2.但是实际上，其实我们希望的是，服务器收到之后，把任务放在一个线程池里面，让线程池去调用路由转发！
    //这里就引入线程池！

    //1.路由服务
    Route route;

    //2.获取线程池单例
    auto tp = ThreadPool<task_t>::GetInstance();

    //3.想办法做到：
    //服务器接收到信息，发送到线程池中，然后由线程池中的线程执行路由转发！
    //但是，进行路由转发的时候，如果中间加了一层线程池，就需要让线程池也知道套接字的描述符！
    std::unique_ptr<UdpServer> Pserver = std::make_unique<UdpServer>(port, 
    [&route, &tp](std::string message, const InetAddr& send_clinet){
        //如果是std::bind绑定一个类内成员函数(非静态)，第一个参数要传指针！
        task_t t = std::bind(&Route::MessageRoute, &route, message, send_clinet);
        //这里要传一个&route是因为，执行类内的函数，必须要由this指针，在外界执行，就只能手动传
        tp->Enqueue(t);
    });


    Pserver->Init();
    Pserver->Start();

    return 0;
}